package com.compomics.proteocloud.db.accessor;

import com.compomics.proteocloud.model.SearchEngineHit;
import com.compomics.proteocloud.model.SearchHit;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Omssahit extends OmssahitTableAccessor implements SearchHit {

    /**
     * The protein id.
     */
    private long proteinId;
    private String annotation;
    private String proteinSequence;

    /**
     * Calls the super class.
     * @param params
     */
    public Omssahit(HashMap params){
        super(params);
    }
    
    /**
     * This constructor reads the spectrum file from a resultset. The ResultSet should be positioned such that a single
     * row can be read directly (i.e., without calling the 'next()' method on the ResultSet).
     *
     * @param aRS ResultSet to read the data from.
     * @throws SQLException when reading the ResultSet failed.
     */
    public Omssahit(ResultSet aRS) throws SQLException {
        super(aRS);
        this.proteinId = aRS.getLong("l_proteinid");
        this.annotation = aRS.getString("annotation");
        this.proteinSequence = aRS.getString("proteinsequence");
    }
    
	/**
     * This method will find the hits from the current connection, based on the specified spectrumid.
     *
     * @param aSpectrumID long with the spectrumid of the spectrum file to find.
     * @param aConn           Connection to read the spectrum File from.
     * @return Spectrumfile with the data.
     * @throws SQLException when the retrieval did not succeed.
     */
    public static List<Omssahit> getHitsFromSpectrumID(long aSpectrumID, Connection aConn) throws SQLException {
    	List<Omssahit> temp = new ArrayList<Omssahit>();
        PreparedStatement ps = aConn.prepareStatement(getBasicSelect() + " where l_spectrumid = ?");
        ps.setLong(1, aSpectrumID);
        ResultSet rs = ps.executeQuery();
        int counter = 0;
        while (rs.next()) {
            counter++;
            temp.add(new Omssahit(rs));
        }
        
        rs.close();
        ps.close();
        return temp;
    }

    /**
     * This method will find the hits from the current connection, based on the specified projectTitle.
     *
     * @param projectTitle The project title.
     * @param conn DB connection.
     * @return List of Crux hits.
     * @throws SQLException when the retrieval did not succeed.
     */
    public static List<Omssahit> getHitsFromProjectTitle(String projectTitle, Connection conn) throws SQLException {
        List<Omssahit> temp = new ArrayList<Omssahit>();
        PreparedStatement ps = conn.prepareStatement("select pr.*, o.*, op.* from omssahit o, spectrum s, project p, protein pr, omssaproteinhit op where o.l_spectrumid = s.spectrumid and o.omssahitid = op.l_omssahitid and pr.proteinid = op.l_proteinid and s.l_projectid = p.projectid and p.title = ?");
        ps.setString(1, projectTitle);
        ResultSet rs = ps.executeQuery();
        while (rs.next()) {
            temp.add(new Omssahit(rs));
        }
        rs.close();
        ps.close();
        return temp;
    }

    public SearchEngineHit.SearchEngineType getType() {
        return SearchEngineHit.SearchEngineType.OMSSA;
    }

    public long getSpectrumId() {
        return iL_spectrumid;
    }

    public long getProteinId() {
        return proteinId;
    }

    public String getProteinAnnotation() {
        return annotation;
    }

    public String getProteinSequence() {
        return proteinSequence;
    }

    public boolean equals(Object obj) {
        if (obj instanceof SearchHit) {
            SearchHit hit = ((SearchHit) obj);
            if (hit.getType() == this.getType()) {
                if (hit.getSpectrumId() == this.getSpectrumId()) {
                    if (hit.getSequence().equals(this.getSequence())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
